package info.liuxing.bean;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
 * 后置处理器：初始化前后进行处理工作
 *
 * BeanPostProcessor原理
 *
 * 在自定义的BeanPostProcessor的实现类中断点，切换到debug视图，即可看到所有调用链
 *
 * 遍历得到容器中所有的BeanPostProcessor；
 * 挨个执行BeforeInitialization，一旦返回null，
 * 跳出循环，不会执行后面的BeanPostProcessor、postProcessBeforeInitialization
 *
 * 核心方法（伪代码）
 * @see org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
 * {
 * 	populateBean(beanName, mbd, instanceWrapper);//给Bean进行属性赋值
 * 	initializeBean {
 * 		applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
 * 		invokeInitMethods(beanName, wrappedBean, mbd);//执行初始化
 * 		applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
 *        }
 * }
 *
 * @author liuxing
 */
@Slf4j
public class MyBeanPostProcessor implements BeanPostProcessor {

    /**
     * @param bean     当前处理的实例
     * @param beanName 实例名
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        log.info("postProcessBeforeInitialization...{}", beanName);
        return bean;
    }

    /**
     * @param bean     当前处理的实例
     * @param beanName 实例名
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        log.info("postProcessAfterInitialization...{}", beanName);
        return bean;
    }
}
